package com.vivz.guess.what.vo;

import java.io.Serializable;
import java.util.Locale;

import android.text.TextUtils;

public class Guess implements Serializable {

	private static final long serialVersionUID = 1596922640154754729L;

	private static final int MIN_GUESS_LENGTH = 4;

	private static final int MAX_GUESS_LENGTH = 5;

	/**
	 * The guess.
	 */
	private final int length;

	/**
	 * The guess.
	 */
	private final String word;

	/**
	 * The weight or clue of the guess in the current game.
	 */
	private final Clue clue;

	/**
	 * A guess is incomplete without a valid guess word and its weight.
	 * 
	 * @param word
	 *            the guess
	 * @param clue
	 *            the weight or clue of the guess
	 */
	public Guess(final int length, final String word, final Clue clue) {

		if (length < MIN_GUESS_LENGTH || length > MAX_GUESS_LENGTH) {

			/*
			 * TODO: Throw a checked user-defined exception instead of IllegalArgumentException.
			 */
			throw new IllegalArgumentException("The guess length must be between " + "max" + " and " + "max" + ".");

		}
		this.length = length;

		if (word == null || word.trim().length() != length) {
			/*
			 * TODO: Throw a checked user-defined exception instead of IllegalArgumentException.
			 */
			throw new IllegalArgumentException("The guess must be a " + length + " lettered word, [" + word
					+ "] was supplied.");
		}
		if (clue == null) {
			/*
			 * TODO: Throw a checked user-defined exception instead of IllegalArgumentException.
			 */
			throw new IllegalArgumentException("The clue must not be null.");
		}

		this.word = word.toUpperCase(Locale.US).trim();
		this.clue = clue;
	}

	public int getLength() {
		return length;
	}

	public String getWord() {
		return word;
	}

	public Clue getClue() {
		return clue;
	}

	@Override
	public boolean equals(final Object o) {

		if (o instanceof String) {
			final String thatGuess = (String) o;
			return thatGuess.equalsIgnoreCase(word);

		} else if (o instanceof Guess) {
			final Guess that = (Guess) o;
			return this.length == that.length && TextUtils.equals(this.word, that.word) && this.clue.equals(that.clue);
		}

		return false;
	}

	@Override
	public int hashCode() {
		int hashCode = 1;
		hashCode = hashCode * 7 + length;
		hashCode = hashCode * 13 + (word == null ? 0 : word.hashCode());
		hashCode = hashCode * 31 + (clue == null ? 0 : clue.hashCode());
		return hashCode;
	}

}
